﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace TestEffectiveCS
{
    
    //操作符is或as优于强制转型
    public class Test03
    {
        public class MyType
        {

            public void DoStuff() { }
        }

        public class NewType : MyType
        {
            public void DoStuff() { }
        }

        public class SecondType
        {
            private MyType _value = new MyType();

            //重载隐式类型转换操作符将SecondType转换为MyType
            public static implicit operator MyType(SecondType t)
            {
                return t._value;
            }

            //显式转换
            //public static explicit operator MyType(SecondType t)
            //{
            //    return t._value;
            //}
            public void DoStuff() { }
        }

        public class Factory
        {
            public static object GetObject()
            {
                return new SecondType();
            }
        }

        object o = Factory.GetObject();

        public Test03()
        {
            ////隐式转换
            //MyType t1 = o as MyType;
            //if (t1 == null) { }
            //else { }

            ////显式转换
            //try
            //{
            //    //编译器不会检测运行时类型SecondType和MyType之间
            //    //是否存在用户自定义的转换
            //    //MyType t2 = (MyType)o;
            //    MyType t2 = o as MyType;
            //    if (t2 == null) { }
            //    else { }
            //}
            //catch { }

            ////中间转换
            //SecondType st = o as SecondType;
            //try
            //{
            //    //MyType t2 = (MyType)st;//显式
            //    MyType t2 = st;//隐式

            //    //如果没有继承关系
            //    //即使已经存在用户自定义转换操作符
            //    //也会产生编译时错误
            //    //MyType t2 = st as MyType;
            //    if (t2 == null) { }
            //    else { }
            //}
            //catch { }

            ////as必需用于引用类型和可以为null的类型
            //int i = o as int;

            //int i = 0;
            ////当不能使用as的时候才使用is来判断
            //if (o is int) i = (int)o;
            //MyType t = null;
            //if ((o as MyType) != null) t = o as MyType;

            //Test03.MyType[] ts = new Test03.MyType[]{
            //    new Test03.MyType(),
            //    new Test03.NewType(),
            //    new Test03.SecondType(), //SecondType已被转换成MyType
            //};
            //object[] os = new object[]{
            //    new Test03.MyType(),
            //    new Test03.NewType(),
            //    new Test03.SecondType(), 
            //};
            //Test03.SecondType[] sts = new Test03.SecondType[] { 
            //        new Test03.SecondType(), 
            //        new Test03.SecondType() };
            //t03.UseCollection(ts);
            //t03.UseCollection(os);
            //t03.UseCollection(sts);
        }

        public void UseCollection(IEnumerable theCollection)
        {
            try
            {
                IEnumerator it = theCollection.GetEnumerator();
                ////遍历所有的MyType类及MyType的继承类
                ////和可以强制转换成MyType的类
                //foreach (MyType t in theCollection)
                //{
                //    t.DoStuff();
                //}
                ////遍历所有的MyType类及MyType的继承类
                ////和可以强制转换成MyType的类
                //while (it.MoveNext())
                //{
                //    MyType t = (MyType)it.Current;
                //    t.DoStuff();
                //}
                ////分别处理MyType类，MyType的继承类
                ////和可以强制转换成MyType的类
                //while (it.MoveNext())
                //{
                //    Type type = it.Current.GetType();
                //    if (type == typeof(MyType))
                //    {
                //        MyType t = (MyType)it.Current;
                //        t.DoStuff();
                //    }
                //    else if (type == typeof(NewType))
                //    {
                //        NewType t = (NewType)it.Current;
                //        t.DoStuff();
                //    }
                //    else if (type == typeof(SecondType))
                //    {
                //        SecondType t = (SecondType)it.Current;
                //        t.DoStuff();
                //    }
                //}
            }
            catch { }
            
        }
    }
}
